package persistentie;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JOptionPane;

import domein.Obstakel;
import domein.Personage;
import domein.SpelBord;
import domein.exceptie.InvalidCategorieException;

/**
 * @author Sam
 * @since 14/03/2011
 */
public class SpelBordMapper {
	
	private Connection connection;
	private Statement statement;
	
	/**
	 * Geeft alle spelborden in de databank terug
	 * @author Sam Verschueren
	 * @return Lijst met alle spelborden
	 */
	public List<SpelBord> geefSpelBorden() {		
		
		List<SpelBord> spelborden = new ArrayList<SpelBord>();
		
		try {
			Connection connection = PersistentieController.getInstance().getConnection();
			Statement statement = connection.createStatement();
			
			ResultSet resultSet = statement.executeQuery("SELECT * FROM Spelbord ORDER BY naam");
			
			while(resultSet.next()) {
				String naam = resultSet.getString("naam");
				int breedte = resultSet.getInt("breedte");
				int hoogte = resultSet.getInt("hoogte");
				
				int[] startPositie = {resultSet.getInt("startX"), resultSet.getInt("startY")};
				int[] eindPositie = {resultSet.getInt("eindX"), resultSet.getInt("eindY")};
				
				SpelBord spelBord = new SpelBord(naam, breedte, hoogte);
				spelBord.setStartPositie(startPositie);
				spelBord.setEindPositie(eindPositie);
				
				spelborden.add(spelBord);
			}
			
			statement.close();
			
		} catch (SQLException e) {
			JOptionPane.showMessageDialog(null, e.getMessage(), "Fout", JOptionPane.ERROR_MESSAGE);
		}
		
		return spelborden;
	}
	
	/**
	 * Plaatst de obstakels op het spelbord.
	 * @author Sam Verschueren
	 * @param spelBord Het spelbord waar de obstakels op moeten geplaatst worden.
	 */
	public void plaatsObstakels(SpelBord spelBord) {
		try {
			Connection connection = PersistentieController.getInstance().getConnection();
			PreparedStatement pStmt = connection.prepareStatement("SELECT * FROM Obstakel, ObstakelsPerSpelbord WHERE Obstakel.naam=ObstakelsPerSpelbord.obstakel AND spelbord=?");
			pStmt.setString(1, spelBord.getNaam());
			
			ResultSet resultSet = pStmt.executeQuery();
			
			while(resultSet.next()) {
				Obstakel obstakel = new Obstakel(resultSet.getString("naam"), resultSet.getString("weergaveText").charAt(0), resultSet.getString("weergaveGrafisch"));
				
				spelBord.geefVak(resultSet.getInt("posX"), resultSet.getInt("posY")).setObstakel(obstakel);
			}
			
			pStmt.close();
		} catch (SQLException e) {
			JOptionPane.showMessageDialog(null, e.getMessage(), "Fout", JOptionPane.ERROR_MESSAGE);
		}
	}
	
	/**
	 * Plaatst de personages op het spelbord.
	 * @author Sam Verschueren
	 * @param spelBord Het spelbord waar de personages op moeten geplaatst worden.
	 */
	public void plaatsPersonages(SpelBord spelBord) {
		try {
			Connection connection = PersistentieController.getInstance().getConnection();
			PreparedStatement pStmt = connection.prepareStatement("SELECT * FROM VijandenPerSpelbord WHERE spelBord=?");
			pStmt.setString(1, spelBord.getNaam());
			
			ResultSet resultSet = pStmt.executeQuery();
			
			while(resultSet.next()) {
				String vijand = resultSet.getString("vijand");
				
				Personage personage = new Personage(vijand, PersistentieController.getInstance().geefPersonageCategorie(vijand));

				spelBord.geefVak(resultSet.getInt("posX"), resultSet.getInt("posY")).setPersonage(personage);
			}
			
			pStmt.close();
		} catch (SQLException e) {
			JOptionPane.showMessageDialog(null, e.getMessage(), "Fout", JOptionPane.ERROR_MESSAGE);
		} catch (IllegalArgumentException e) {
			JOptionPane.showMessageDialog(null, e.getMessage(), "Fout", JOptionPane.ERROR_MESSAGE);
		} catch (InvalidCategorieException e) {
			JOptionPane.showMessageDialog(null, e.getMessage(), "Fout", JOptionPane.ERROR_MESSAGE);
		}
	}
	
	/**
	 * @author Sam Verschueren
	 * @param spelbord Het nieuwe spelbord dat in de databank moet gestoken worden.
	 */
	public void maakSpelbord(SpelBord spelbord) {
		try {
			Connection connection = PersistentieController.getInstance().getConnection();
			Statement statement = connection.createStatement();
			
			statement.executeUpdate("INSERT INTO Spelbord(naam, breedte, hoogte) VALUES('" + spelbord.getNaam() + "', '" + spelbord.geefSpelBord()[0].length + "', '" + spelbord.geefSpelBord().length + "')");
			
			statement.close();
		} catch (SQLException e) {
			JOptionPane.showMessageDialog(null, e.getMessage(), "Fout", JOptionPane.ERROR_MESSAGE);
		}
	}

	public List<Obstakel> geefObstakels() {
		List<Obstakel> obstakels = new ArrayList<Obstakel>();
		
		try {
			Connection connection = PersistentieController.getInstance().getConnection();
			Statement statement = connection.createStatement();
			
			ResultSet resultSet = statement.executeQuery("SELECT * FROM Obstakel ORDER BY naam");
			
			while(resultSet.next()) {
				String naam = resultSet.getString("naam");
				String textWeergave = resultSet.getString("weergaveText");
				String grafisch = resultSet.getString("weergaveGrafisch");
				
				Obstakel obstakel = new Obstakel(naam, textWeergave.charAt(0), grafisch);
				
				obstakels.add(obstakel);
			}
			
			statement.close();
			
		} catch (SQLException e) {
			JOptionPane.showMessageDialog(null, e.getMessage(), "Fout", JOptionPane.ERROR_MESSAGE);
		}
		
		return obstakels;
	}

	public void plaatsObstakel(SpelBord spelBord, Obstakel obstakel, int posX, int posY) {
		try {
			Connection connection = PersistentieController.getInstance().getConnection();
			Statement statement = connection.createStatement();
			
			statement.executeUpdate("INSERT INTO ObstakelsPerSpelbord(spelbord, obstakel, posX, posY) VALUES('" + spelBord.getNaam() + "', '" + obstakel.getNaam() + "', '" + posX + "', '" + posY + "')");
			
			statement.close();
		} catch (SQLException e) {
			JOptionPane.showMessageDialog(null, e.getMessage(), "Fout", JOptionPane.ERROR_MESSAGE);
		}
	}
	
	public void verwijderObstakel(SpelBord spelBord, int posX, int posY) {
		connection = PersistentieController.getInstance().getConnection();		
		try{
			statement = connection.createStatement();

			statement.executeUpdate("DELETE * FROM ObstakelsPerSpelbord WHERE (spelbord='" + spelBord.getNaam() + "' AND posX=" + posX + " AND posY=" + posY + ")");
			statement.close();
		}
		catch(SQLException sqlException){
			JOptionPane.showMessageDialog(null, sqlException.getMessage(), "Fout", JOptionPane.ERROR_MESSAGE);
			PersistentieController.getInstance().closeConnection();
		}
	}

	public void plaatsPersonage(SpelBord hetSpelbord, Personage hetPersonage, int posX, int posY) {
		connection = PersistentieController.getInstance().getConnection();		
		try{
			statement = connection.createStatement();

			statement.executeUpdate("INSERT INTO VijandenPerSpelbord(spelBord, vijand, posX, posY) VALUES('" + hetSpelbord.getNaam() + "', '" + hetPersonage.getNaam() + "', '" + posX + "', '" + posY + "')");
			statement.close();
		}
		catch(SQLException sqlException){
			JOptionPane.showMessageDialog(null, sqlException.getMessage(), "Fout", JOptionPane.ERROR_MESSAGE);
			PersistentieController.getInstance().closeConnection();
		}
	}

	public void verwijderPersonage(SpelBord hetSpelbord, int posX, int posY) {
		connection = PersistentieController.getInstance().getConnection();		
		try{
			statement = connection.createStatement();

			statement.executeUpdate("DELETE * FROM VijandenPerSpelbord WHERE (spelbord='" + hetSpelbord.getNaam() + "' AND posX=" + posX + " AND posY=" + posY + ")");
			statement.close();
		}
		catch(SQLException sqlException){
			JOptionPane.showMessageDialog(null, sqlException.getMessage(), "Fout", JOptionPane.ERROR_MESSAGE);
			PersistentieController.getInstance().closeConnection();
		}
	}

	public void zetEindPositie(SpelBord hetSpelbord, int[] einde) {
		connection = PersistentieController.getInstance().getConnection();		
		try{
			statement = connection.createStatement();

			statement.executeUpdate("UPDATE Spelbord SET eindX=" + einde[0] + ", eindY=" + einde[1] + " WHERE naam='" + hetSpelbord.getNaam() + "'");
			statement.close();
		}
		catch(SQLException sqlException){
			JOptionPane.showMessageDialog(null, sqlException.getMessage(), "Fout", JOptionPane.ERROR_MESSAGE);
			PersistentieController.getInstance().closeConnection();
		}
	}
	
	public void zetStartPositie(SpelBord hetSpelbord, int[] start) {
		connection = PersistentieController.getInstance().getConnection();		
		try{
			statement = connection.createStatement();

			statement.executeUpdate("UPDATE Spelbord SET startX=" + start[0] + ", startY=" + start[1] + " WHERE naam='" + hetSpelbord.getNaam() + "'");
			statement.close();
		}
		catch(SQLException sqlException){
			JOptionPane.showMessageDialog(null, sqlException.getMessage(), "Fout", JOptionPane.ERROR_MESSAGE);
			PersistentieController.getInstance().closeConnection();
		}
	}

	public void verwijderSpelbord(String naam) {
		connection = PersistentieController.getInstance().getConnection();		
		try{
			statement = connection.createStatement();

			statement.executeUpdate("DELETE * FROM Spelbord WHERE naam='" + naam + "'");
			statement.executeUpdate("DELETE * FROM VijandenPerSpelbord WHERE spelBord='" + naam + "'");
			statement.executeUpdate("DELETE * FROM ObstakelsPerSpelbord WHERE spelbord='" + naam + "'");
			
			statement.close();
		}
		catch(SQLException sqlException){
			JOptionPane.showMessageDialog(null, sqlException.getMessage(), "Fout", JOptionPane.ERROR_MESSAGE);
			PersistentieController.getInstance().closeConnection();
		}
	}
}
